package com.zeyu.framework.tools.mq.sender;

import com.zeyu.framework.core.configuration.RabbitMqConfiguration;
import com.zeyu.framework.tools.mq.struct.CommandType;
import com.zeyu.framework.tools.mq.struct.MQHeader;
import com.zeyu.framework.tools.mq.struct.MQMessage;
import com.zeyu.framework.tools.mq.struct.MessageType;
import com.zeyu.framework.tools.mq.struct.ServiceType;
import com.zeyu.framework.tools.mq.utils.EncryptUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

import java.nio.charset.Charset;

/**
 * 发送MQ message,不同message使用不同的模板
 * Created by zeyuphoenix on 2016/12/31.
 */
@Component
public class MQMessageSender {

    // ================================================================
    // Constants
    // ================================================================

    /**
     * logger
     */
    private static final Logger logger = LoggerFactory.getLogger(MQMessageSender.class);

    // ================================================================
    // Fields
    // ================================================================

    @Autowired
    @Qualifier(value = "rabbitTemplate")
    private AmqpTemplate amqpTemplate;

    @Autowired
    @Qualifier(value = "faoutRabbitTemplate")
    private AmqpTemplate faoutRabbitTemplate;

    @Autowired
    @Qualifier(value = "rpcRabbitTemplate")
    private AmqpTemplate rpcRabbitTemplate;

    // ================================================================
    // Constructors
    // ================================================================

    // ================================================================
    // Methods from/for super Interfaces or SuperClass
    // ================================================================

    // ================================================================
    // Public or Protected Methods
    // ================================================================

    /**
     * 点对点-公共信息
     */
    public void sendCommon(MQMessage message) {
        logger.info("发送公共信息: " + message);
        this.amqpTemplate.convertAndSend(RabbitMqConfiguration.ROUTING_KEY_COMMON, message);
    }

    /**
     * 点对点-心跳信息
     */
    public void sendHeart(MQMessage message) {
        logger.info("发送心跳信息: " + message);
        this.amqpTemplate.convertAndSend("", message);
    }

    /**
     * RPC应答
     */
    public MQMessage sendRPC(MQMessage message) {
        logger.info("发送RPC请求: " + message);
        Object response = this.rpcRabbitTemplate.convertSendAndReceive(RabbitMqConfiguration.QUEUE_RPC_REQUEST, message);
        logger.info("接收RPC应答信息: " + response);
        return (MQMessage) response;
    }

    /**
     * 发布-订阅
     */
    public void sendPublish(MQMessage message) {
        logger.info("发送发布-定于信息: " + message);
        this.faoutRabbitTemplate.convertAndSend(message);
    }

    /**
     * 构建MQ消息
     * @param type 消息类型
     * @param serviceType 服务类型
     * @param commandType 命令类型
     * @param sn 设备sn
     * @param body 发送主题
     * @return 消息
     */
    public static MQMessage buildMQMessage(MessageType type, ServiceType serviceType,
                                           CommandType commandType, String sn, String body) {
        return buildMQMessage(type, serviceType, commandType, sn, false, body);
    }

    /**
     * 构建MQ消息
     * @param type 消息类型
     * @param serviceType 服务类型
     * @param commandType 命令类型
     * @param sn 设备sn
     * @param encrypt 是否加密
     * @param body 发送主题
     * @return 消息
     */
    public static MQMessage buildMQMessage(MessageType type, ServiceType serviceType,
                                           CommandType commandType, String sn,
                                           boolean encrypt, String body) {
        MQMessage mqMessage = new MQMessage();

        // 设置header
        MQHeader mqHeader = new MQHeader();
        mqHeader.setLength(10);
        mqHeader.setType(type.value());
        mqHeader.setServiceId(serviceType.value());
        mqHeader.setCommandId(commandType.value());
        mqHeader.setSessionId(System.currentTimeMillis());
        mqHeader.setSn(sn);

        // 设置message
        mqMessage.setMqHeader(mqHeader);
        mqMessage.setEncrypt(encrypt);
        mqMessage.setBody(body.getBytes(Charset.forName(EncryptUtils.CHART_SET)));

        return mqMessage;
    }

    // ================================================================
    // Getter & Setter
    // ================================================================

    // ================================================================
    // Private Methods
    // ================================================================

    // ================================================================
    // Inner or Anonymous Class
    // ================================================================

    // ================================================================
    // Test Methods
    // ================================================================

}
